package com.sunrise.gateway.commons.watermark;

import com.dap.utils.DateUtil;
import com.google.common.base.Charsets;
import com.sunrise.gateway.commons.SafeUrlBase64Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.awt.*;
import java.io.IOException;
import java.util.*;
import java.util.List;

/**
 * Created by wangmin on 2018/4/27.
 */
public abstract class WatermarkParamUtils {
    private static Logger logger = LoggerFactory.getLogger(WatermarkParamUtils.class);

    /**
     * 将字符串分割
     * 输入样例:
     * str:"&gh&j&j&&k&", separator:'&'
     * 结果为 ["gh", "j", "j", "k"]
     */
    private static List<String> mySplitString(String str, char separator) {
        List<String> res = new ArrayList<>();

        int idx = 0, nextIdx;
        while (idx < str.length()) {
            nextIdx = str.indexOf(separator, idx);
            if (nextIdx < 0) {
                res.add(str.substring(idx));
                break;
            } else {
                String element = str.substring(idx, nextIdx);
                if (element.length() > 0)
                    res.add(element);
                idx = nextIdx + 1;
            }
        }

        return res;
    }


    private static WatermarkParam generateWatermarkParamFromAliyunParamMap(Map<String, String> paramMap) {
        String text = paramMap.get("text");

        String fontName = null;
        if (null != paramMap.get("type")) {
            switch (paramMap.get("type")) {
                case "d3F5LXplbmhlaQ":
                    fontName = "文泉驿正黑";
                    break;
                case "d3F5LW1pY3JvaGVp":
                    fontName = "文泉微米黑";
                    break;
                case "ZmFuZ3poZW5nc2h1c29uZw":
                    fontName = "方正书宋";
                    break;
                case "ZmFuZ3poZW5na2FpdGk":
                    fontName = "方正楷体";
                    break;
                case "ZmFuZ3poZW5naGVpdGk":
                    fontName = "方正黑体";
                    break;
                case "ZmFuZ3poZW5nZmFuZ3Nvbmc":
                    fontName = "方正仿宋";
                    break;
                case "ZHJvaWRzYW5zZmFsbGJhY2s":
                    fontName = "DroidSansFallback";
                    break;
            }
        }

        Integer fontStyle = null;

        Integer fontSize = null;
        if (paramMap.get("size") != null) {
            try {
                fontSize = Integer.parseInt(paramMap.get("size"));
            } catch (Exception e) {
            }
        }

        Color color = null;
        if (paramMap.get("color") != null) {
            try {
                color = Color.decode("#"+paramMap.get("color"));
            } catch (Exception e) {
            }
        }

        int x = Integer.parseInt(paramMap.get("x"));

        int y = Integer.parseInt(paramMap.get("y"));

        Float alpha = null;
        if (paramMap.get("t") != null) {
            try {
                alpha = Integer.parseInt(paramMap.get("t")) / 100F;
            } catch (Exception e) {
            }
        }

        return new WatermarkParam(text, fontName, fontStyle, fontSize, color, x, y, alpha);
    }



    /**
     * 按照分隔符, 分解为key value 的 map
     * 输入样例:
     * paramStr:"text_546L5pWPIOadreW3niBbZGF0ZVRpbWUsZm9ybWF0PXl5eXktTU0tZGRd,color_FF0000,t_60,g_se,x_20,y_2"
     * paramSeparatorCh:','
     * keyValueSeparatorCh:'_'
     */
    private static Map<String, String> parseParamMap(String paramStr, char paramSeparatorCh, char keyValueSeparatorCh) {
        List<String> pl = mySplitString(paramStr, paramSeparatorCh);

        Map<String, String> res = new HashMap<>();
        for (String p : pl) {
            int separatorIdx = p.indexOf(keyValueSeparatorCh);
            if (separatorIdx < 0)
                continue;
            res.put(p.substring(0, separatorIdx), p.substring(separatorIdx + 1));
        }
        return res;
    }

    private static String parseTextFormat(String str) {
        Map<String, String> param;
        int idx = str.indexOf(',');
        if (idx >= 0) {
            param = parseParamMap(str.substring(idx + 1), '&', '=');
        } else {
            param = new HashMap<>();
        }

        switch (str.substring(0, idx)) {
            case "dateTime":
                String format = param.get("format");
                if (null == format) {
                    return null;
                } else {
                    return DateUtil.getSimpleDateFormat(format).format(new Date());
                }
            default:
                return null;
        }
    }

    private static String handleWatermarkText(String base64Text) {
        try {
            String sourceText = new String(SafeUrlBase64Utils.safeUrlBase64Decode(base64Text), Charsets.UTF_8);
            StringBuilder sb = new StringBuilder();
            int idx = 0;
            while (idx < sourceText.length()) {
                int leftIdx = sourceText.indexOf('[', idx);
                if (leftIdx < 0) {
                    sb.append(sourceText.substring(idx));
                    break;
                }

                int rightIdx = sourceText.indexOf(']', leftIdx + 1);
                if (rightIdx < 0) {
                    sb.append(sourceText.substring(idx));
                    break;
                }

                String parsedStr = parseTextFormat(sourceText.substring(leftIdx + 1, rightIdx));
                if (parsedStr != null)
                    sb.append(parsedStr);

                idx = rightIdx + 1;
            }
            return sb.toString();
        } catch (IOException e) {
            logger.debug("", e);
            return "";
        }
    }

    private static Map<String, String> handleOneWatermarkParam(String watermarkParam) {
        Map<String, String> watermarkParamMap = parseParamMap(watermarkParam, ',', '_');
        String text = watermarkParamMap.get("text");
        if (StringUtils.isEmpty(text))
            return watermarkParamMap;

        watermarkParamMap.put("text", handleWatermarkText(text));

        return watermarkParamMap;
    }


    static java.util.List<WatermarkParam> parseWatermarkParams(String watermarkParamsStr) throws Exception {
        if (StringUtils.isEmpty(watermarkParamsStr))
            return null;
        logger.debug("watermarkParamsStr = {}", watermarkParamsStr);

        java.util.List<String> paramStrList = mySplitString(watermarkParamsStr, ';');

        java.util.List<WatermarkParam> watermarkParamList = new ArrayList<>();
        for (String paramStr : paramStrList) {
            if (!StringUtils.isEmpty(paramStr)) {
                Map<String, String> paramMap = handleOneWatermarkParam(paramStr);
                WatermarkParam param = generateWatermarkParamFromAliyunParamMap(paramMap);
                watermarkParamList.add(param);
            }
        }
        return watermarkParamList;
    }
}
